package org.ysh.core.attachment;

import org.apache.commons.io.FilenameUtils;
import org.ysh.annotation.AdditionInfoResolver;
import org.ysh.core.utils.ClassUtils;
import org.ysh.core.utils.StringUtils;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

/**
 * 附件附件信息处理工厂类
 */
public class AdditionInfoResolverFactory {

    private static final Map<String, AttachmentAdditionInfoResolver> ADDITION_MAP = new HashMap<>();

    public AdditionInfoResolverFactory(String... resolverPackages) {
        String defaultPackage = "com.ruoyi.common.core.utils.attachment";
        boolean contains = false;
        if (StringUtils.isNotEmpty(resolverPackages)) {
            for (String pack : resolverPackages) {
                if (defaultPackage.equals(pack)) {
                    contains = true;
                    break;
                }
            }

            for (String packageName : resolverPackages) {
                Set<Class<?>> classSet = ClassUtils.getClasses(packageName);
                loadAdditionInfoResolvers(classSet);
            }
        }

        if (!contains) {
            Set<Class<?>> classSet = ClassUtils.getClasses(defaultPackage);
            loadAdditionInfoResolvers(classSet);
        }

    }

    private void loadAdditionInfoResolvers(Set<Class<?>> classes) {
        Class<AttachmentAdditionInfoResolver> additionInfoClass = AttachmentAdditionInfoResolver.class;
        if (null != classes && !classes.isEmpty()) {
            for (Class<?> clazz : classes) {
                if (Arrays.stream(clazz.getInterfaces()).anyMatch(interfaceClass->interfaceClass == additionInfoClass)) {
                    AdditionInfoResolver resolver = clazz.getDeclaredAnnotation(AdditionInfoResolver.class);
                    if (resolver != null) {
                        String[] extensions = resolver.extensions();
                        try {
                            AttachmentAdditionInfoResolver info = (AttachmentAdditionInfoResolver) clazz.getConstructor().newInstance();
                            if (StringUtils.isNotEmpty(extensions)) {
                                for (String ext : extensions) {
                                    ADDITION_MAP.put(ext, info);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        AdditionInfoResolverFactory additionInfoFactory = new AdditionInfoResolverFactory();
        AdditionInfo additionInfo = new AdditionInfo();
        additionInfo.setUserName("Lisssi");
        additionInfo.setTime(new Date());
        additionInfo.setHost("192.168.1.1");
        String filePath = "C:\\Users\\hxs_2\\Desktop\\南京海关\\1111.xls";
        additionInfoFactory.addAdditionInfo(new File(filePath),additionInfo);

        additionInfo = additionInfoFactory.readAdditionInfo(Files.newInputStream(Paths.get(filePath)), FilenameUtils.getExtension(filePath));
        System.out.println(additionInfo);
    }

    /**
     * 添加文件附件信息
     *
     * @param tmpFile
     * @param additionInfo
     * @throws Exception
     */
    public void addAdditionInfo(File tmpFile, AdditionInfo additionInfo) throws Exception {
        String fileName = tmpFile.getName();
        String extension = FilenameUtils.getExtension(fileName);
        if (extension != null) {
            extension = extension.toLowerCase();
        }
        AttachmentAdditionInfoResolver attachmentAdditionInfoResolver = ADDITION_MAP.getOrDefault(extension, UnsupportedAdditionInfoResolver.getInstance());
        attachmentAdditionInfoResolver.addAdditionInfo(tmpFile, additionInfo);
    }

    /**
     * 读取文件附加信息
     *
     * @param is
     * @param fileExt
     * @return
     * @throws Exception
     */
    public AdditionInfo readAdditionInfo(InputStream is, String fileExt) throws Exception {
        if (fileExt != null) {
            fileExt = fileExt.toLowerCase();
        }
        AttachmentAdditionInfoResolver attachmentAdditionInfoResolver = ADDITION_MAP.getOrDefault(fileExt, UnsupportedAdditionInfoResolver.getInstance());
        return attachmentAdditionInfoResolver.readAdditionInfo(is);
    }

}
